package com.techsoul.module.accounting.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.techsoul.common.core.exception.ExcelException;
import com.techsoul.common.core.exception.ParamException;
import com.techsoul.common.core.manager.AsyncManager;
import com.techsoul.common.core.pojo.vo.UserVo;
import com.techsoul.common.core.util.ServletUtils;
import com.techsoul.common.core.util.bean.BeanUtils;
import com.techsoul.common.core.util.collection.ListUtils;
import com.techsoul.common.core.util.collection.MapUtils;
import com.techsoul.common.core.util.id.IdWorker;
import com.techsoul.common.core.util.lang.DateUtils;
import com.techsoul.common.core.util.lang.NumberUtils;
import com.techsoul.common.core.util.lang.StringUtils;
import com.techsoul.common.core.util.poi.ExcelExport;
import com.techsoul.common.security.service.TokenService;
import com.techsoul.module.accounting.mapper.AccAccountingApHisMapper;
import com.techsoul.module.accounting.mapper.AccApSkuMonthlySettlementMapper;
import com.techsoul.module.accounting.mapper.AccountingApMapper;
import com.techsoul.module.accounting.pojo.entity.AccAccountingApHis;
import com.techsoul.module.accounting.pojo.entity.AccApSkuMonthlySettlement;
import com.techsoul.module.accounting.pojo.param.AccApSkuMonthlySettlementSaveParam;
import com.techsoul.module.accounting.pojo.param.AccApSkuMonthlySettlementSearchParam;
import com.techsoul.module.accounting.pojo.param.AccountingApSearchParam;
import com.techsoul.module.accounting.pojo.vo.AccApSkuMonthlySettlementViewVo;
import com.techsoul.module.accounting.pojo.vo.AccApSkuMonthlySettlementVo;
import com.techsoul.module.accounting.pojo.vo.AccountingApVo;
import com.techsoul.module.accounting.service.IAccApSkuMonthlySettlementService;
import com.techsoul.module.accounting.task.AccApSkuMonthlySettlementAsyncFactory;
import com.techsoul.module.basic.mapper.StoreMapper;
import com.techsoul.module.basic.mapper.SupplierMapper;
import com.techsoul.module.basic.pojo.entity.Store;
import com.techsoul.module.basic.pojo.entity.Supplier;
import com.techsoul.module.basic.pojo.vo.StoreVo;
import com.techsoul.module.basic.pojo.vo.SupplierVo;
import com.techsoul.module.goods.mapper.SpuMapper;
import com.techsoul.module.goods.pojo.entity.Spu;
import com.techsoul.module.order.mapper.SalesOrderHisMapper;
import com.techsoul.module.order.mapper.SalesOrderItemHisMapper;
import com.techsoul.module.order.mapper.SalesOrderItemMapper;
import com.techsoul.module.order.mapper.SalesOrderMapper;
import com.techsoul.module.order.pojo.entity.SalesOrder;
import com.techsoul.module.order.pojo.entity.SalesOrderHis;
import com.techsoul.module.order.pojo.entity.SalesOrderItemHis;
import com.techsoul.module.order.pojo.param.SalesOrderItemSearchParam;
import com.techsoul.module.order.pojo.vo.SalesOrderItemVo;
import com.techsoul.module.system.service.IConfigService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 财务月度sku汇总 Service实现
 *
 * @author liuen
 * @date 2021-06-01
 */
@Slf4j
@Service
@Transactional(readOnly = true)
public class AccApSkuMonthlySettlementServiceImpl implements IAccApSkuMonthlySettlementService {

    @Autowired
    private IdWorker idWorker;

    @Autowired
    private AccApSkuMonthlySettlementMapper mapper;
    @Autowired
    private AccountingApMapper apmapper;
    @Autowired
    private AccAccountingApHisMapper aphismapper;
    @Autowired
    private SalesOrderItemHisMapper salesOrderItemHismapper;
    @Autowired
    private SalesOrderItemMapper salesOrderItemmapper;
    @Autowired
    private SalesOrderHisMapper salesOrderHismapper;
    @Autowired
    private SalesOrderMapper salesordermapper;
    @Autowired
    private StoreMapper storeMapper;

    @Autowired
    private SupplierMapper supplierMapper;
    @Autowired
    private SpuMapper spuMapper;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private IConfigService configService;

    /**
     * 新增
     * @param params
     * @return
     */
    @Transactional(readOnly = false)
    @Override
    public void insert(AccApSkuMonthlySettlementSearchParam params) {
        UserVo user = tokenService.getLoginUser(ServletUtils.getRequest()).getUser();
        AsyncManager.me().execute(AccApSkuMonthlySettlementAsyncFactory.asyncInsert(params, user));
    }

    /**
     * 异步新增
     * @param params
     * @return
     */
    @Transactional(readOnly = false)
    @Override
    public void asyncInsert(AccApSkuMonthlySettlementSearchParam params, UserVo user) {
        String jbmonth =  params.getJobMonth();
        String mon = jbmonth.split("-")[1];
        String year = jbmonth.split("-")[0];

        int month = Integer.valueOf(mon);
        int yr =  Integer.valueOf(year);
        List<AccApSkuMonthlySettlementVo> findExist = this.mapper.findByJobMothYr(params.getJobMonth());
        if(findExist!=null&&findExist.size()>0){
            for(int i = 0;i<findExist.size();i++){
                AccApSkuMonthlySettlementVo accApSkuMonthlySettlementVo = (AccApSkuMonthlySettlementVo)findExist.get(i);
                this.delete(accApSkuMonthlySettlementVo.getId());
            }

        }
        this.generateMonthlySum(month,yr,params, user);
        //    this.deleteFromOldAddToHistory(month,yr,params, user);

    }


    /**
     * 删除
     * @param id
     * @return
     */
    @Transactional(readOnly = false)
    @Override
    public Integer delete(String id) {
        return this.mapper.deleteById(id);
    }

    /**
     * 批量删除
     * @param idList
     */
    @Transactional(readOnly = false)
    @Override
    public Integer batchDelete(List<String> idList) {
        if (ListUtils.isNotEmpty(idList)) {
            return this.mapper.deleteBatchIds(idList);
        } else {
            return 0;
        }
    }

    /**
     * 修改
     * @param params
     * @return
     */
    @Transactional(readOnly = false)
    @Override
    public Integer update(AccApSkuMonthlySettlementSaveParam params) {
        AccApSkuMonthlySettlement entityFromDb = this.mapper.selectById(params.getId());
        if (entityFromDb == null) {
            throw new ParamException("id=" + params.getId());
        }
        UserVo user = tokenService.getLoginUser(ServletUtils.getRequest()).getUser();
        BeanUtils.copyProperties(params, entityFromDb);
        entityFromDb.preUpdate(user.getId());
        return this.mapper.updateById(entityFromDb);
    }

    /**
     * 详情
     * @param id
     * @return
     */
    @Override
    public AccApSkuMonthlySettlementVo findById(String id) {
        return this.mapper.findById(id);
    }

    /**
     * 列表
     * @param params
     * @return
     */
    @Override
    public List<AccApSkuMonthlySettlementVo> findAll(AccApSkuMonthlySettlementSearchParam params) {
        UserVo sysuser = tokenService.getLoginUser(ServletUtils.getRequest()).getUser();
        if(!StringUtils.isNull(sysuser.getSite())){
            params.setSite(sysuser.getSite());
        }
        return this.mapper.findAll(params);
    }

    /**
     * 列表-分页
     * @param params
     * @param current
     * @param pageSize
     * @return
     */
    @Override
    public IPage<AccApSkuMonthlySettlementVo> findAll(AccApSkuMonthlySettlementSearchParam params, Integer current, Integer pageSize) {
        UserVo sysuser = tokenService.getLoginUser(ServletUtils.getRequest()).getUser();
        if(!StringUtils.isNull(sysuser.getSite())){
            params.setSite(sysuser.getSite());
        }
        return this.mapper.findAll(new Page<>(current, pageSize), params);
    }

    @Override
    public String exportData(AccApSkuMonthlySettlementSearchParam params) {
        String baseDir = configService.findByConfigKey("project.attachment.baseDir");
        String baseUrl = configService.findByConfigKey("project.attachment.baseUrl");
        String fileName = "";
        List<AccApSkuMonthlySettlementVo> list = this.findAll(params);
        if(!StringUtils.isNull(params.getStoreId())&&list!=null&&list.size()>0){
            AccApSkuMonthlySettlementVo accountingApVo =(AccApSkuMonthlySettlementVo)list.get(0);
            fileName = "结算汇总-"+accountingApVo.getStoreName() + "-"+params.getJobMonthFr().replace("-", "")+ "-"+params.getJobMonthTo().replace("-", "")+".xlsx";
        }
        try {
            new ExcelExport(null, AccApSkuMonthlySettlementVo.class).setDataList(list).writeFile(baseDir + fileName).close();
        } catch (Exception e) {
            log.error("财务月度sku汇总导出失败", e);
            throw new ExcelException(e.getMessage());
        }
        return baseUrl + fileName;
    }

    @Transactional(readOnly = false)
    @Override
    public String generateMonthlySumData(String site,Integer month,Integer year,UserVo user,AccApSkuMonthlySettlementSearchParam params){
        String rt = "success";
        String mon = "";
        if(month<10){
            mon = "0".concat(String.valueOf(month));
        }else{
            mon = String.valueOf(month);
        }
        String monthYear = String.valueOf(year).concat("-").concat(mon);
        params.setJobMonth(monthYear);
        List<AccountingApVo> detailSums = this.apmapper.findSumAps(params);
        //List<AccountingApVo> detailRtSums = this.apmapper.findSumReturns(params);
        int j=0;
        for(int i=0;i<detailSums.size();i++){
            AccountingApVo sumaccountingApVo = (AccountingApVo)detailSums.get(i);
            AccApSkuMonthlySettlement entity = new AccApSkuMonthlySettlement();
            entity.setPayCust(sumaccountingApVo.getPayCust());
            if(sumaccountingApVo.getSumAmount()!=null){
                entity.setAmount(new BigDecimal(sumaccountingApVo.getSumAmount()));
            }else{
                entity.setAmount(new BigDecimal(0.0));
            }
            if(sumaccountingApVo.getSumQty()!=null){
                entity.setWtCnt(new BigDecimal(sumaccountingApVo.getSumQty()));
            }else{
                entity.setWtCnt(new BigDecimal(0.0));
            }
            if(sumaccountingApVo.getSumRtQty()!=null){
                entity.setReturnQty(sumaccountingApVo.getSumRtQty());
            }else{
                entity.setReturnQty(0);
            }

            if(sumaccountingApVo.getSumRtAmt()!=null){
                entity.setReturnAmt(sumaccountingApVo.getSumRtAmt());
            }else{
                entity.setReturnAmt(0.0);
            }
       /*    for(int v=j;j<detailRtSums.size();v++){
               AccountingApVo sumaccountingRtApVo = (AccountingApVo)detailRtSums.get(v);
              if(sumaccountingRtApVo.getCustSpuId().equals(sumaccountingApVo.getCustSpuId())){
                 if(sumaccountingRtApVo.getCustSkuId().equals(sumaccountingApVo.getCustSkuId())){
                     if(sumaccountingRtApVo.getSumRtQty()!=null){
                         entity.setReturnQty(sumaccountingRtApVo.getSumRtQty());
                     }else{
                         entity.setReturnQty(0);
                     }

                     if(sumaccountingRtApVo.getSumRtAmt()!=null){
                         entity.setReturnAmt(sumaccountingRtApVo.getSumRtAmt());
                     }else{
                         entity.setReturnAmt(0.0);
                     }

                     j=v;
                     break;
                 }

              }

           }*/

            entity.setCustCashPaymentAmt(sumaccountingApVo.getSumCustCash());
            entity.setCustMilePaymentAmt(sumaccountingApVo.getSumCustMile());
            entity.setOriginalSellQty(sumaccountingApVo.getSumOriginalSellQty());
            entity.setStoreId(sumaccountingApVo.getStoreId());
            entity.setCargoObjectNo(sumaccountingApVo.getCargoObjectNo());
            entity.setCargoObjectName(sumaccountingApVo.getCargoObjectName());
            entity.setCustSkuId(sumaccountingApVo.getCustSkuId());
            entity.setStoreName(sumaccountingApVo.getStoreName());
            if(StringUtils.isNull(sumaccountingApVo.getBrandName())){
                if(!StringUtils.isNull(sumaccountingApVo.getCustSpuId())&&!StringUtils.isNull(sumaccountingApVo.getMallId()))
                {
                    List<Spu> spus= this.spuMapper.findByCustSpuNo(sumaccountingApVo.getCustSpuId(),sumaccountingApVo.getMallId());
                    if(spus!=null&&spus.size()>0){
                        Spu spu = (Spu)spus.get(0);
                        entity.setBrandName(spu.getBrandName());
                    }
                }
            }else{
                entity.setBrandName(sumaccountingApVo.getBrandName());
            }
            entity.setPayCust(sumaccountingApVo.getPayCust());
            if(sumaccountingApVo.getSumAmtAr()!=null){
                entity.setAmtAr(new BigDecimal(sumaccountingApVo.getSumAmtAr()));
            }else{
                entity.setAmtAr(new BigDecimal(0.0));
            }
            entity.setShipperName(sumaccountingApVo.getShipperName());
            entity.setCustSpuId(sumaccountingApVo.getCustSpuId());
            entity.setStoreName(sumaccountingApVo.getStoreName());
            entity.setMallName(sumaccountingApVo.getMallName());
            entity.setMallId(sumaccountingApVo.getMallId());
            //   Double rate = NumberUtils.div(sumaccountingApVo.getContractRate().doubleValue(),sumaccountingApVo.getWtCnt().doubleValue());
            if(sumaccountingApVo.getRate()!=null) {
                entity.setRate(new BigDecimal(sumaccountingApVo.getRate())); // 买入单价
            }else{
                entity.setRate(new BigDecimal(0.0));
            }
            //  Double sellrate = NumberUtils.div(sumaccountingApVo.getAmtCur().doubleValue(),sumaccountingApVo.getWtCnt().doubleValue());
            if(sumaccountingApVo.getAmtGenAr()!=null) {
                entity.setExrate(new BigDecimal(sumaccountingApVo.getAmtGenAr())); // 卖出单价
            }else{
                entity.setExrate(new BigDecimal(0.0));
            }
            entity.setJobMonth(monthYear);
            if(sumaccountingApVo.getSumContractAmount()!=null){
                entity.setAmtCur(new BigDecimal(sumaccountingApVo.getSumContractAmount()));
            }else{
                entity.setAmtCur(new BigDecimal(0.0));
            }
            entity.setId(idWorker.nextId() + "").preInsert(user.getId());
            this.mapper.insert(entity);
        }
        // this.apmapper.updateStatusToSettled(monthYear);
        return rt;
    }
    /**
     * 月汇总
     *
     * @param month
     * @return
     */
    @Transactional(readOnly = false)
    @Override
    public String generateMonthlySum(Integer month,Integer year,AccApSkuMonthlySettlementSearchParam params, UserVo user) {
        return  this.generateMonthlySumData(user.getSite(), month, year,user,params);

    }
    /**
     * 移入历史数据表
     *
     * @param month
     * @return
     */
    @Transactional(readOnly = false)
    @Override
    public String deleteFromOldAddToHistory(Integer month,Integer year,AccApSkuMonthlySettlementSearchParam params, UserVo user) {
        String rt = "success";
        String mon = "";
        if(month<10){
            mon = "0".concat(String.valueOf(month));
        }else{
            mon = String.valueOf(month);
        }
        String monthYear = String.valueOf(year).concat("-").concat(mon);
        params.setJobMonth(monthYear);
        AccountingApSearchParam accountingApSearchParam = new AccountingApSearchParam();
        accountingApSearchParam.setMonthYear(monthYear);
        List<AccountingApVo> aps = this.apmapper.findAll(accountingApSearchParam);
        SalesOrderItemSearchParam salesOrderItemSearchParam = new SalesOrderItemSearchParam();
        salesOrderItemSearchParam.setOrderTime(monthYear);
        List<SalesOrderItemVo> salesOrderItems = this.salesOrderItemmapper.findAll(salesOrderItemSearchParam);
        for(int i=0;i<aps.size();i++){
            AccountingApVo accountingAp = (AccountingApVo)aps.get(i);
            AccAccountingApHis accAccountingApHis = new AccAccountingApHis();
            BeanUtils.copyProperties(accountingAp, accAccountingApHis);
            accAccountingApHis.setId(idWorker.nextId() + "").preInsert(user.getId());
            this.aphismapper.insert(accAccountingApHis);
            this.apmapper.deleteById(accountingAp.getId());
        }
        List<String> orderids = new ArrayList();
        for(int j=0;j<salesOrderItems.size();j++){
            SalesOrderItemVo salesOrderItem = (SalesOrderItemVo)salesOrderItems.get(j);
            SalesOrderItemHis salesOrderItemHis = new SalesOrderItemHis();
            BeanUtils.copyProperties(salesOrderItem, salesOrderItemHis);
            salesOrderItemHis.setId(idWorker.nextId() + "").preInsert(user.getId());
            if(!orderids.contains(salesOrderItem.getSalesOrderId())){
                orderids.add(salesOrderItem.getSalesOrderId());
                SalesOrder salesOrder =  this.salesordermapper.selectById(salesOrderItem.getSalesOrderId());
                SalesOrderHis salesOrderHis = new SalesOrderHis();
                BeanUtils.copyProperties(salesOrder, salesOrderHis);
                salesOrderItemHis.setId(idWorker.nextId() + "").preInsert(user.getId());
                this.salesOrderHismapper.insert(salesOrderHis);
                this.salesordermapper.deleteById(salesOrder.getId());
            }

            this.salesOrderItemHismapper.insert(salesOrderItemHis);
            this.salesOrderItemmapper.deleteById(salesOrderItem.getId());

        }

        return rt;

    }
    /**
     * 品牌排行列表-分页
     * @param params
     * @param current
     * @param pageSize
     * @return
     */
    @Override
    public IPage<AccApSkuMonthlySettlementViewVo> brandRateView(AccApSkuMonthlySettlementSearchParam params, Integer current, Integer pageSize){
        return this.mapper.brandRateView(new Page<>(current, pageSize), params);
    }

    /**
     * SPU排行列表-分页
     * @param params
     * @param current
     * @param pageSize
     * @return
     */
    @Override
    public IPage<AccApSkuMonthlySettlementViewVo> spuRateView(AccApSkuMonthlySettlementSearchParam params, Integer current, Integer pageSize) {
        return this.mapper.spuRateView(new Page<>(current, pageSize), params);
    }
    /**
     * 供应商排行列表-分页
     * @param params
     * @param current
     * @param pageSize
     * @return
     */
    @Override
    public IPage<AccApSkuMonthlySettlementViewVo> supplierRateView(AccApSkuMonthlySettlementSearchParam params, Integer current, Integer pageSize) {
        IPage<AccApSkuMonthlySettlementViewVo> aps = this.mapper.supplierRateView(new Page<>(0, 1000),params);
        List<AccApSkuMonthlySettlementViewVo> reaps = new ArrayList<AccApSkuMonthlySettlementViewVo>();
        for(int i=0; i < aps.getRecords().size();i++){
            AccApSkuMonthlySettlementViewVo accApSkuMonthlySettlementViewVo =
                    (AccApSkuMonthlySettlementViewVo)aps.getRecords().get(i);
            Supplier store = this.supplierMapper.selectById(accApSkuMonthlySettlementViewVo.getPayCust());
            accApSkuMonthlySettlementViewVo.setShipperName(store.getSupplierName());
            reaps.add(accApSkuMonthlySettlementViewVo);
        }
        aps.setRecords(reaps);
        return aps;


    }
    /**
     * 店铺排行列表-分页
     * @param params
     * @return
     */
    @Override
    public IPage<AccApSkuMonthlySettlementViewVo> storeRateView(AccApSkuMonthlySettlementSearchParam params) {
        IPage<AccApSkuMonthlySettlementViewVo> aps = this.mapper.storeRateView(new Page<>(0, 1000),params);
        List<AccApSkuMonthlySettlementViewVo> reaps = new ArrayList<AccApSkuMonthlySettlementViewVo>();
        for(int i=0; i < aps.getRecords().size();i++){
            AccApSkuMonthlySettlementViewVo accApSkuMonthlySettlementViewVo =
                    (AccApSkuMonthlySettlementViewVo)aps.getRecords().get(i);
            StoreVo store = this.storeMapper.findByCode(accApSkuMonthlySettlementViewVo.getStoreId());
            accApSkuMonthlySettlementViewVo.setStoreName(store.getStoreName());
            reaps.add(accApSkuMonthlySettlementViewVo);
        }
        aps.setRecords(reaps);
        return aps;
    }

    /**
     * 单品销售列表-分页
     * @param params
     * @param current
     * @param pageSize
     * @return
     */
    @Override
    public IPage<AccApSkuMonthlySettlementViewVo> skuRateView(AccApSkuMonthlySettlementSearchParam params, Integer current, Integer pageSize) {

        return this.mapper.skuRateView(new Page<>(current, pageSize), params);
    }
    /**
     * 单品销售分析
     * @param params
     * @param current
     * @param pageSize
     * @return
     */
    @Override
    public IPage<AccApSkuMonthlySettlementViewVo> skuSpuRateReport(AccApSkuMonthlySettlementSearchParam params, Integer current, Integer pageSize) {
        if(StringUtils.isNull(params.getCustSkuId())){
            return this.mapper.spuRateReport(new Page<>(current, pageSize), params);
        }else{
            return this.mapper.skuSpuRateReport(new Page<>(current, pageSize), params);
        }

    }

    /**
     * 获得地区订单总数
     *
     * @return
     */
    @Override
    public AccApSkuMonthlySettlementViewVo countTotalSale(AccApSkuMonthlySettlementSearchParam params) {
        return this.mapper.countTotalSale(params);
    }
    /**
     * 获得地区采购总数
     *
     * @return
     */
    @Override
    public AccApSkuMonthlySettlementViewVo countTotalPurchase(AccApSkuMonthlySettlementSearchParam params) {
        return this.mapper.countTotalPurchase(params);
    }
    /**
     * 获按月统计曲线
     *
     * @return
     */
    @Override
    public Map<String, Object> countMonthlyLineChart(AccApSkuMonthlySettlementSearchParam params) {
        Map<String, Object> map = MapUtils.newHashMap();
        List<AccApSkuMonthlySettlementViewVo> accApSkuMonthlySettlementViewVos = this.mapper.countMonthlyLineChart(params);
        if (ListUtils.isNotEmpty(accApSkuMonthlySettlementViewVos)) {
            List<String> jobMonthList = accApSkuMonthlySettlementViewVos.stream().map(accApSkuMonthlySettlementViewVo -> accApSkuMonthlySettlementViewVo.getJobMonth()).collect(Collectors.toList());
            List<Double> sumAmtArList = accApSkuMonthlySettlementViewVos.stream().map(accApSkuMonthlySettlementViewVo -> accApSkuMonthlySettlementViewVo.getSumAmtAr()).collect(Collectors.toList());
            List<Double> sumAmountList = accApSkuMonthlySettlementViewVos.stream().map(accApSkuMonthlySettlementViewVo -> accApSkuMonthlySettlementViewVo.getSumAmount()).collect(Collectors.toList());
            map.put("jobMonthList", jobMonthList);
            map.put("sumAmtArList", sumAmtArList);
            map.put("sumAmountList", sumAmountList);
        }
        return map;
    }
    @Override
    public List<AccApSkuMonthlySettlementViewVo> reportSum(AccApSkuMonthlySettlementSearchParam accountingApSearchParam){
        return this.mapper.reportSum(accountingApSearchParam);
    }
}
